﻿using Contact.API.Data.Core;
using Contact.API.Data.Interface;
using Contact.API.Models;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Contact.API.Data
{
    public class MongoContactRepository
        : IContactRepository
    {
        private readonly ContactContext _contactContext;
        public MongoContactRepository(ContactContext contactContext)
        {
            _contactContext = contactContext;
        }

        public async Task<bool> AddContactInfoAsync(BaseUserInfo baseUserInfo, CancellationToken cancellactionToken)
        {

            await _contactContext.Contactbooks.InsertOneAsync(new ContactBook() { UserId = baseUserInfo.UserId, Contacts = new List<Core.Contact>() }, null, cancellactionToken);
            return true;
        }

        public async Task<List<Core.Contact>> GetContactsAsync(int userId, CancellationToken cancellationToken)
        {
            var contact = (await _contactContext.Contactbooks.FindAsync(c => c.UserId == userId, null, cancellationToken)).FirstOrDefault();
            if (contact == null)
            {
                return new List<Core.Contact>();
            }
            return contact.Contacts;
        }

        public async Task<bool> TagContactAsync(int userId, int contactId, List<string> tags, CancellationToken cancellationToken)
        {
            var filterDefinition = Builders<ContactBook>.Filter.And(Builders<ContactBook>.Filter.Eq(c => c.UserId, userId),
                Builders<ContactBook>.Filter.Eq("Contacts.UserId", contactId));
            var update = Builders<ContactBook>.Update.Set("Contats.$.Tags",tags);

            var result =await _contactContext.Contactbooks.UpdateManyAsync(filterDefinition,update,null,cancellationToken);
            return result.MatchedCount == result.ModifiedCount;
        }

        public async Task<bool> UpdateContactInfoAsync(BaseUserInfo baseUserInfo, CancellationToken cancellactionToken)
        {
            var filterDefinition = Builders<ContactBook>.Filter.Eq(c => c.UserId, baseUserInfo.UserId);
            var list = (await _contactContext.Contactbooks.FindAsync(filterDefinition, null, cancellactionToken)).ToList();
            if (list.Count < 0)
            {
                return true;
            }
            var ids = list.FirstOrDefault()?.Contacts.Select(s => s.UserId);

            var filterDefine = Builders<ContactBook>.Filter.And(
                Builders<ContactBook>.Filter.Eq(c => c.UserId, baseUserInfo.UserId),
                Builders<ContactBook>.Filter.ElemMatch(c => c.Contacts, contact => contact.UserId == baseUserInfo.UserId));
            var updateDefinition = Builders<ContactBook>.Update
                .Set("Contacts.$.Name", baseUserInfo.Name)
                .Set("Contacts.$.Title", baseUserInfo.Title)
                .Set("Contacts.$.Avatar", baseUserInfo.Avatar)
                .Set("Contacts.$.Company", baseUserInfo.Company);
            var updateResult = _contactContext.Contactbooks.UpdateMany(filterDefine, updateDefinition, null, cancellactionToken);
            return updateResult.MatchedCount == updateResult.ModifiedCount;
        }
    }
}
